home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / gas / src138.zoo / as.c < prev    next >
C/C++ Source or Header  |  1991-01-21  |  8KB  |  309 lines

  1. /* as.c - GAS main program.
  2.    Copyright (C) 1987 Free Software Foundation, Inc.
  3.  
  4. This file is part of GAS, the GNU Assembler.
  5.  
  6. GAS is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GAS is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GAS; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /*
  21.  * Main program for AS; a 32-bit assembler of GNU.
  22.  * Understands command arguments.
  23.  * Has a few routines that don't fit in other modules because they
  24.  * are shared.
  25.  *
  26.  *
  27.  *            bugs
  28.  *
  29.  * : initialisers
  30.  *    Since no-one else says they will support them in future: I
  31.  * don't support them now.
  32.  *
  33.  */
  34.  
  35. #ifdef _POSIX_SOURCE
  36. #include <sys/types.h>    /* For pid_t in signal.h */
  37. #endif
  38. #include <signal.h>
  39.  
  40. #define COMMON
  41. #include "as.h"
  42. #include "struc-symbol.h"
  43. #include "write.h"
  44.         /* Warning!  This may have some slightly strange side effects
  45.            if you try to compile two or more assemblers in the same
  46.            directory!
  47.          */
  48.  
  49. #ifndef SIGTY
  50. #define SIGTY int
  51. #endif
  52.  
  53. SIGTY got_sig();
  54.  
  55. #ifdef DONTDEF
  56. static char * gdb_symbol_file_name;
  57. long int gdb_begin();
  58. #endif
  59.  
  60. char *myname;        /* argv[0] */
  61. extern char version_string[];
  62.  
  63. main(argc,argv)
  64. int    argc;
  65. char    **argv;
  66. {
  67.     int    work_argc;    /* variable copy of argc */
  68.     char    **work_argv;    /* variable copy of argv */
  69.     char    *arg;        /* an arg to program */
  70.     char    a;        /* an arg flag (after -) */
  71.     static const int sig[] = { SIGHUP, SIGINT, SIGPIPE, SIGTERM, 0};
  72.  
  73.     extern int bad_error;    /* Did we hit a bad error ? */
  74.  
  75.     char    *stralloc();    /* Make a (safe) copy of a string. */
  76.     void    symbol_begin();
  77.     void    read_begin();
  78.     void    write_object_file();
  79.  
  80.     for(a=0;sig[a]!=0;a++)
  81.         if(signal(sig[a], SIG_IGN) != SIG_IGN)
  82.             signal(sig[a], got_sig);
  83.  
  84. #ifdef atarist
  85.     _binmode(1);
  86. #endif
  87.     myname=argv[0];
  88.     bzero (flagseen, sizeof(flagseen)); /* aint seen nothing yet */
  89.     out_file_name    = "a.out";    /* default .o file */
  90.     symbol_begin();        /* symbols.c */
  91.     subsegs_begin();        /* subsegs.c */
  92.     read_begin();            /* read.c */
  93.     md_begin();            /* MACHINE.c */
  94.     input_scrub_begin();        /* input_scrub.c */
  95. #ifdef DONTDEF
  96.     gdb_symbol_file_name = 0;
  97. #endif
  98.     /*
  99.      * Parse arguments, but we are only interested in flags.
  100.      * When we find a flag, we process it then make it's argv[] NULL.
  101.      * This helps any future argv[] scanners avoid what we processed.
  102.      * Since it is easy to do here we interpret the special arg "-"
  103.      * to mean "use stdin" and we set that argv[] pointing to "".
  104.      * After we have munged argv[], the only things left are source file
  105.      * name(s) and ""(s) denoting stdin. These file names are used
  106.      * (perhaps more than once) later.
  107.      */
  108.     work_argc = argc-1;        /* don't count argv[0] */
  109.     work_argv = argv+1;        /* skip argv[0] */
  110.     for (;work_argc--;work_argv++) {
  111.         arg = * work_argv;    /* work_argv points to this argument */
  112.  
  113.         if (*arg!='-')        /* Filename. We need it later. */
  114.             continue;    /* Keep scanning args looking for flags. */
  115.         if (arg[1] == '-' && arg[2] == 0) {
  116.             /* "--" as an argument means read STDIN */
  117.             /* on this scan, we don't want to think about filenames */
  118.             * work_argv = "";    /* Code that means 'use stdin'. */
  119.             continue;
  120.         }
  121.                 /* This better be a switch. */
  122.         arg ++;        /* -> letter. */
  123.  
  124.         while (a = * arg)  {/* scan all the 1-char flags */
  125.             arg ++;    /* arg -> after letter. */
  126.             a &= 0x7F;    /* ascii only please */
  127.             if (flagseen[a])
  128.                 as_warn("%s: Flag option -%c has already been seen!",myname,a);
  129.             flagseen[a] = TRUE;
  130.             switch (a) {
  131.             case 'f':
  132.                 break;    /* -f means fast - no need for "app" preprocessor. */
  133.  
  134.             case 'D':
  135.                 /* DEBUG is implemented: it debugs different */
  136.                 /* things to other people's assemblers. */
  137.                 break;
  138.  
  139. #ifdef DONTDEF
  140.             case 'G':    /* GNU AS switch: include gdbsyms. */
  141.                 if (*arg)    /* Rest of argument is file-name. */
  142.                     gdb_symbol_file_name = stralloc (arg);
  143.                 else if (work_argc) {    /* Next argument is file-name. */
  144.                     work_argc --;
  145.                     * work_argv = NULL; /* Not a source file-name. */
  146.                     gdb_symbol_file_name = * ++ work_argv;
  147.                 } else
  148.                     as_warn( "%s: I expected a filename after -G",myname);
  149.                 arg = "";    /* Finished with this arg. */
  150.                 break;
  151. #endif
  152.  
  153. #ifndef WORKING_DOT_WORD
  154.             case 'k':
  155.                 break;
  156. #endif
  157.  
  158.             case 'L': /* -L means keep L* symbols */
  159.                 break;
  160.  
  161.             case 'o':
  162.                 if (*arg)    /* Rest of argument is object file-name. */
  163.                     out_file_name = stralloc (arg);
  164.                 else if (work_argc) {    /* Want next arg for a file-name. */
  165.                     * work_argv = NULL; /* This is not a file-name. */
  166.                     work_argc--;
  167.                     out_file_name = * ++ work_argv;
  168.                 } else
  169.                     as_warn("%s: I expected a filename after -o. \"%s\" assumed.",myname,out_file_name);
  170.                 arg = "";    /* Finished with this arg. */
  171.                 break;
  172.  
  173.             case 'R':
  174.                 /* -R means put data into text segment */
  175.                 break;
  176.  
  177.             case 'v':
  178. #ifdef    VMS
  179.                 {
  180.                 extern char *compiler_version_string;
  181.                 compiler_version_string = arg;
  182.                 }
  183. #else /* not VMS */
  184.                 fprintf(stderr,version_string);
  185.                 if(*arg && strcmp(arg,"ersion"))
  186.                     as_warn("Unknown -v option ignored");
  187. #endif
  188.                 while(*arg) arg++;    /* Skip the rest */
  189.                 break;
  190.  
  191.             case 'W':
  192.                 /* -W means don't warn about things */
  193.                 break;
  194.  
  195.             default:
  196.                 --arg;
  197.                 if(md_parse_option(&arg,&work_argc,&work_argv)==0)
  198.                     as_warn("%s: I don't understand '%c' flag!",myname,a);
  199.                 if(arg && *arg)
  200.                     arg++;
  201.                 break;
  202.             }
  203.         }
  204.         /*
  205.          * We have just processed a "-..." arg, which was not a
  206.          * file-name. Smash it so the
  207.          * things that look for filenames won't ever see it.
  208.          *
  209.          * Whatever work_argv points to, it has already been used
  210.          * as part of a flag, so DON'T re-use it as a filename.
  211.          */
  212.         *work_argv = NULL; /* NULL means 'not a file-name' */
  213.     }
  214. #ifdef DONTDEF
  215.     if (gdb_begin(gdb_symbol_file_name) == 0)
  216.         flagseen ['G'] = 0;    /* Don't do any gdbsym stuff. */
  217. #endif
  218.     /* Here with flags set up in flagseen[]. */
  219.     perform_an_assembly_pass(argc,argv); /* Assemble it. */
  220.     if (seen_at_least_1_file() && !bad_error)
  221.         write_object_file();/* relax() addresses then emit object file */
  222.     input_scrub_end();
  223.     md_end();            /* MACHINE.c */
  224. #ifndef    VMS
  225.     exit(bad_error);            /* WIN */
  226. #else    /* VMS */
  227.     exit(!bad_error);            /* WIN */
  228. #endif    /* VMS */
  229. }
  230.  
  231.  
  232. /*            perform_an_assembly_pass()
  233.  *
  234.  * Here to attempt 1 pass over each input file.
  235.  * We scan argv[*] looking for filenames or exactly "" which is
  236.  * shorthand for stdin. Any argv that is NULL is not a file-name.
  237.  * We set need_pass_2 TRUE if, after this, we still have unresolved
  238.  * expressions of the form (unknown value)+-(unknown value).
  239.  *
  240.  * Note the un*x semantics: there is only 1 logical input file, but it
  241.  * may be a catenation of many 'physical' input files.
  242.  */
  243. perform_an_assembly_pass (argc, argv)
  244. int    argc;
  245. char **    argv;
  246. {
  247.     char *    buffer;        /* Where each bufferful of lines will start. */
  248.     void    read_a_source_file();
  249.     int saw_a_file = 0;
  250.  
  251.     text_fix_root        = NULL;
  252.     data_fix_root        = NULL;
  253.     need_pass_2        = FALSE;
  254.  
  255.     argv++;            /* skip argv[0] */
  256.     argc--;            /* skip argv[0] */
  257.     while (argc--) {
  258.         if (*argv) {        /* Is it a file-name argument? */
  259.             /* argv -> "" if stdin desired, else -> filename */
  260.             if (buffer = input_scrub_new_file (*argv) ) {
  261.                 saw_a_file++;
  262.                 read_a_source_file(buffer);
  263.             }
  264.         }
  265.         argv++;            /* completed that argv */
  266.     }
  267.     if(!saw_a_file)
  268.         if(buffer = input_scrub_new_file("") )
  269.             read_a_source_file(buffer);
  270. }
  271.  
  272. /*
  273.  *            stralloc()
  274.  *
  275.  * Allocate memory for a new copy of a string. Copy the string.
  276.  * Return the address of the new string. Die if there is any error.
  277.  */
  278.  
  279. char *
  280. stralloc (str)
  281. char *    str;
  282. {
  283.     register char *    retval;
  284.     register long int    len;
  285.  
  286.     len = strlen (str) + 1;
  287.     retval = xmalloc (len);
  288.     (void)strcpy (retval, str);
  289.     return (retval);
  290. }
  291.  
  292. lose()
  293. {
  294.     as_fatal( "%s: 2nd pass not implemented - get your code from random(3)",myname );
  295. }
  296.  
  297. SIGTY
  298. got_sig(sig)
  299. int sig;
  300. {
  301.     s